package com.yu.util;

import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Random;

import com.alibaba.fastjson.JSONObject;
import com.google.common.collect.Maps;
import com.yu.model.Balance;
import com.yu.model.Log;
import com.yu.model.LuckyMoney;
import com.yu.model.Snatch;
import com.yu.model.Task;
import com.yu.model.Taskrecord;
import com.yu.model.User;
import com.yu.model.UserClub;
import com.yu.model.Withdraw;

public class CashUtil {
	
	
	   //  用户=1 车友会=2  车友会私密账户=3 官方=10
    public final static int    AMOUNT_TYPE_USER = 1;
    public final static int    AMOUNT_TYPE_CLUB = 2;
    public final static int    AMOUNT_TYPE_PRIVATE = 3;
    
    public final static int    AMOUNT_TYPE_ACT = 4;
    public final static int    AMOUNT_TYPE_OFFICIAL = 10;
    
    
    
	public static final int CashEventCharge = 0;		// 充值

	public static final int CashEventSendRp= 1;			// 发红包
	public static final int CashEventGetRp= 2;			// 收红包
	public static final int CashEventRefoundRp= 3;		// 红包退款

	public static final int CashEventBuyProd= 10;		// 商品购买
	public static final int CashEventRefoundProd= 11;	// 商品退款

	public static final int CashEventActivityFee= 20;	// 车友会是指活动支出，用户是指活动报名预付款
	public static final int CashEventActivityIn= 21;	// 车友会是指活动报名收到的钱，用户暂无意义
	public static final int CashEventActivityRefound= 22;	// 车友会活动剩余的钱退款

	public static final int CashEventWithDraw= 100;		// 提现
	
	public static final int CashEventWithDrawBack= 102;		// 提现 退款
	public static final int CashEventWelfare= 101;		// Speed福利(包括管理员工资)
	
	
	public final static int eSpeedJumpToRpCash = 100;
	public final static int eSpeedJumpToRpExp = 101;
	
	public static final int  eSpeedJumpToDetailProdDetail = 306;
	public static final int  eSpeedJumpToDetailShopDetail = 307;
	
	
	// 贡献币任务
	public final static int 		TASKPT_JOIN_CLUB			 		 = 19;		// 首次加入车友会
	public final static int 		TASKPT_BUY_DETAIL			 		 = 20;		// 首次完善汽车购买信息
	public final static int 		TASKPT_CAR_GALLERY				 	 = 21;		// 首次上传汽车外观照片(车身内饰都有)
	public final static int 		TASKPT_USRE_INTRO			 		 = 22;		// 首次完善个性签名
	public final static int 		TASKPT_SHARE_SQUARE			 		 = 23;		// 首次街拍分享
	public final static int 		TASKPT_SHARE			 		 	 = 24;		// 首次分享比如游记
	public final static int 		TASKPT_ANSWER_A_QUESTION			 = 25;		// 首次回答问题
	public final static int 		TASKPT_ASK_A_QUESTION				 = 26;		// 首次提问题

	public final static int 		TASKPT_PROD_COMMEN			 		 = 27;		// 商品晒单
	public final static int 		TASKPT_QA_BEST			 			 = 28;		// 问题被置为精华

	public final static int 		TASKPT_SERVICE_FIX_INS			 	 = 29;		// 保险维修
	public final static int 		TASKPT_SERVICE_MAINTAIN			 	 = 30;		// 汽车保养
	public final static int 		TASKPT_SERVICE_FIX_SELF			 	 = 31;		// 自费维修
	public final static int 		TASKPT_ACTIVITY_JOIN			 	 = 32;		// 参加活动
	public final static int 		TASKPT_BUY_OTHER			 		 = 33;		// 购买其他商品和服务
	
	public final static int 		TASKPT_WITH_DRAW			 		 = 34;		// 购买其他商品和服务
	
	public final static int 		TASKPT_SYSTEM_LEVEL			 		 = 99;		// 购买其他商品和服务
	
	
	public final static int 		Point_PROD_COMMEN			 		 = 27;		// 商品晒单
	public final static int 		Point_QA_BEST			 			 = 28;		// 问题被置为精华

	public final static int 		Point_SERVICE_FIX_INS			 	 = 29;		// 保险维修
	public final static int 		Point_SERVICE_MAINTAIN			 	 = 30;		// 汽车保养
	public final static int 		Point_SERVICE_FIX_SELF			 	 = 31;		// 自费维修
	public final static int 		Point_ACTIVITY_JOIN			 	 = 32;		// 参加活动
	// 纯利润*20%（有封顶总价*8%） * 10
	public final static int 		Point_BUY_OTHER			 		 = 33;		// 购买其他商品和服务
	
	
	public final static int 		Point_WithDraw			 		 = 34;		// 提现
	

	public static final int         PointEventTask = 1000;		// 贡献币增加
    /**
     * 
     * @param type
     * @param accid
     * @param amount  金额
     */
	public static void updateAmount(int type,Long accid,BigDecimal amount,int event,int eventid){
		if (amount.abs().compareTo(new BigDecimal(0.001))==1){
			Balance balance = Balance.dao.findFirst("select * from club_cashbalance where type="+type+" and accid="+accid);
			if (balance != null){
				balance.set("amount", amount.add(balance.getBigDecimal("amount")));
				// 活动提现
				if (type == 4 && amount .doubleValue() < 0){
					int point = balance.getInt("point");
					if (point > 0){
						Log log = new Log();
						log.set("type", AMOUNT_TYPE_ACT);
						log.set("accid", accid);
					    log.set("amount", new BigDecimal(0));
					    log.set("point", -1 * point);
					    log.set("event", event);
					    log.set("eventid", eventid);
					    log.set("createtime", System.currentTimeMillis());
					    log.set("valid", 0);
					    log.set("subtype", 1);
					    log.set("title", "活动提现");
					    log.save();
					    balance.set("point", 0);
					}
				}
				balance.update();
			} else {
				balance = new Balance();
				balance.set("type", type);
				balance.set("accid", accid);
				balance.set("amount", amount);
				balance.set("createtime", System.currentTimeMillis());
				balance.save();
			}
			
			Log log = new Log();
			log.set("type", type);
			log.set("accid", accid);
		    log.set("amount", amount);
		    log.set("event", event);
		    log.set("eventid", eventid);
		    log.set("createtime", System.currentTimeMillis());
		    log.set("valid", 0);
		    log.save();
		}
	}
	
	
    /**
     * 
     * @param type
     * @param accid
     * @param amount  金额
     */
	public static void updatePoint(Long userid,int point,int event,int eventid,int taskid){
		try{
			String logtitle = null;
			if (taskid != TASKPT_SYSTEM_LEVEL){
				if (point > 0){
					if (TASKPT_BUY_OTHER != taskid){
						Log exist = Log.dao.findFirst("select * from club_cashlog where subtype = 1 and type =" + CashUtil.AMOUNT_TYPE_USER +" and accid =" + userid +" and event =" + event +" and eventid=" + eventid );
						if (exist != null){
							return;
						}
					}
				}
				Task task = Task.dao.findById(taskid);
				if (task != null){
					if (task.getInt("subtype") == 1 && task.getInt("type") == 0){
						Taskrecord taskrecord = Taskrecord.dao.findFirst("select * from club_taskrecord where valid > -1 and taskid ="+taskid+" and userid ="+userid);
						if (taskrecord == null){
							taskrecord = new Taskrecord();
							taskrecord.set("userid", userid);
							taskrecord.set("taskid", taskid);
							taskrecord.set("count", 1);
							taskrecord.set("status", 1);
							taskrecord.set("createtime", System.currentTimeMillis());
							taskrecord.set("valid", 0);
							taskrecord.save();
						}
					}
					logtitle = task.getStr("title");
				}
				point  = point > 1? point:(point * Math.max(1, task.getInt("experience")) );
			} else{
				logtitle = "老用户等级折现";
			}
			Balance balance = Balance.dao.findFirst("select * from club_cashbalance where type="+AMOUNT_TYPE_USER+" and accid="+userid);
			if (balance != null){
				balance.set("point", balance.getInt("point") + point);
				if (point > 0){
					balance.set("sumpoint", balance.getInt("sumpoint") + point);
				} else if(TASKPT_BUY_OTHER == taskid && point < -1){
					balance.set("sumpoint", balance.getInt("sumpoint") + point);
				}
				balance.update();
			} else {
				balance = new Balance();
				balance.set("type", AMOUNT_TYPE_USER);
				balance.set("accid", userid);
				balance.set("amount", new BigDecimal(0));
				balance.set("point", Math.max(point, 0));
				balance.set("sumpoint", Math.max(point, 0));
				balance.set("createtime", System.currentTimeMillis());
				balance.save();
			}
			
			Log log = new Log();
			log.set("type", AMOUNT_TYPE_USER);
			log.set("accid", userid);
		    log.set("amount", new BigDecimal(0));
		    log.set("point", point);
		    log.set("event", event);
		    log.set("eventid", eventid);
		    log.set("createtime", System.currentTimeMillis());
		    log.set("valid", 0);
		    log.set("subtype", 1);
		    log.set("title", logtitle);
		    if(TASKPT_BUY_OTHER == taskid && point < -1){
		    	log.set("title", "购买商品退款");
		    } else if (TASKPT_WITH_DRAW == taskid ){
		    	log.set("title", "活动提现");
		    }
		    log.save();
		    
		} catch(Exception e){
			e.printStackTrace();
		}
	}
	
	
   public static String newTradeNo(){
    	StringBuffer tradeNo = new StringBuffer(new SimpleDateFormat("yyyyMMddHHmmss").format(new Date(System.currentTimeMillis())));
    	// 获得随机数  
    	double pross = (1 + new Random().nextDouble()) * Math.pow(10, 8);  
    	tradeNo.append(String.valueOf(pross).substring(2, 10))   ;  
    	return tradeNo.toString();
    }
	   
   
   public static void sendRed2ToClub(Long clubid,BigDecimal amount,int prodid,Long userid,String prodtitle,String comment,int event,int eventid){
		int luckymoneyid = 0;
		UserClub userCnt = UserClub.dao.findFirst("select count(id) as count from club_userclub" );
		int count = Integer.parseInt(String.valueOf(userCnt.get("count")));
		if (amount.doubleValue() <0.5){
			return ;
		} else if (amount.intValue() <2){
			amount = new BigDecimal(2);
		}
		int limit = (int )(amount.doubleValue() * 1.5);
		if(limit > count){
			limit = count;
		}
		LuckyMoney luckymoney = new LuckyMoney();
		luckymoney.set("fromtype", AMOUNT_TYPE_CLUB);
		luckymoney.set("fromid", clubid);
		
		luckymoney.set("targettype", AMOUNT_TYPE_CLUB);
		luckymoney.set("targetid", clubid);
		luckymoney.set("limit",limit);
		luckymoney.set("amount",amount);
		luckymoney.set("experience",0);
		luckymoney.set("comment",comment);
		
		luckymoney.set("status", 1);
		luckymoney.set("createtime", System.currentTimeMillis());
		luckymoney.set("valid", 0);
		
		luckymoney.set("index", 0);
		luckymoney.set("lon", 0);
		luckymoney.set("lat", 0);
		luckymoney.set("gendreq",null);
		luckymoney.set("distreq",null);
		luckymoney.set("levelreq", "5,99");
		luckymoney.set("batreq",null);
		luckymoney.set("event", event);
		luckymoney.set("eventid", eventid);
		try{
			luckymoney.save();
		} catch (Exception e) {
			e.printStackTrace();
		}
		
		luckymoneyid = luckymoney.getInt("id");
   	
		if (luckymoneyid >0){
			Integer[] splitmoney = resortLuckyMoney(amount.multiply(new BigDecimal(100)).intValue(), limit);
	    	for(int i = 0 ; splitmoney != null && i < splitmoney.length;i++){
	    		Snatch natch = new Snatch();
	    		natch.set("luckymid", luckymoneyid);
	    		natch.set("index", i+1);
	    		natch.set("status", 0);
	    		natch.set("amount", new BigDecimal(splitmoney[i]).divide(new BigDecimal(100)).setScale(2, BigDecimal.ROUND_HALF_UP));
	    		natch.save();
	    	}
			Map<String,Object> obj1 = Maps.newHashMap();
			Map<String,Object> data = Maps.newHashMap();
			data.put("type", 4);
			data.put("subtype", 304);
			Map<String,Object> info = Maps.newHashMap();
			info.put("title", "福利消费");
			info.put("subtitle", "汽车用品消费");
			info.put("eventdetail", "车友会提供厂家直供汽车用品");
			
			info.put("event", prodtitle);
			info.put("eventjump", eSpeedJumpToDetailProdDetail);
			info.put("eventid", prodid);
			info.put("action", "领取现金红包");
			info.put("actionjump", eSpeedJumpToRpCash);
			info.put("actionid", luckymoneyid);
			User user = User.dao.findFirst("select * from club_users where userid ="+userid);
			info.put("fromid", userid);
			info.put("fromtype", 1);
			info.put("fromname", user.get("name"));
			info.put("fromavatar", user.get("avatar"));
			info.put("fromgender", user.get("gender"));
			data.put("info", info);
			obj1.put("Data", JSONObject.toJSONString(data));
			obj1.put("Desc", "现金红包");
			QQIMComponent oneComponent = new QQIMComponent();
			System.out.println(oneComponent.sendMsgToClub(obj1, clubid));
		}
   }
	public static void sendRedToClub(Long clubid,BigDecimal amount){
		// 红包
		LuckyMoney luckymoney = new LuckyMoney();
		luckymoney.set("fromtype", AMOUNT_TYPE_CLUB);
		luckymoney.set("fromid", clubid);
		
		luckymoney.set("targettype", AMOUNT_TYPE_CLUB);
		luckymoney.set("targetid", clubid);
		
		UserClub userclub = UserClub.dao.findFirst("select count(DISTINCT userid) as count  from club_userclub where club_userclub.clubid ="+clubid);
		int count =  0;
		try {
			count =	Integer.parseInt(String.valueOf( userclub.get("COUNT")));
		} catch (Exception e){
			
		}
		int limit = count *3/10;
		luckymoney.set("limit", limit);
		luckymoney.set("amount", amount);
		luckymoney.set("experience", 0);
		luckymoney.set("index", 0);
		luckymoney.set("lon", 0);
		luckymoney.set("lat", 0);
		luckymoney.set("gendreq",null);
		luckymoney.set("distreq",null);
		luckymoney.set("levelreq",null);
		luckymoney.set("batreq",null);
		luckymoney.set("status",1);
		luckymoney.set("createtime", System.currentTimeMillis());
		luckymoney.set("comment","大吉大利");
		luckymoney.save();
		Integer[] splitmoney = resortLuckyMoney(amount.multiply(new BigDecimal(100)).intValue(), limit);
    	int luckymoneyid = luckymoney.getInt("id");
    	for(int i = 0 ; splitmoney != null && i < splitmoney.length;i++){
    		Snatch natch = new Snatch();
    		natch.set("luckymid", luckymoneyid);
    		natch.set("index", i+1);
    		natch.set("status", 0);
    		natch.set("amount", new BigDecimal(splitmoney[i]).divide(new BigDecimal(100)).setScale(2, BigDecimal.ROUND_HALF_UP));
    		natch.save();
    	}
		// 日志
    	Log log = new Log();
		log.set("type", AMOUNT_TYPE_CLUB);
		log.set("accid", clubid);
	    log.set("amount", amount);
	    log.set("event", 1);
	    log.set("eventid", luckymoneyid);
	    log.set("createtime", System.currentTimeMillis());
	    log.set("valid", 0);
	    log.save();
	    
	    CashUtil.updateAmount(CashUtil.AMOUNT_TYPE_CLUB, clubid, amount.multiply(new BigDecimal(-1)), CashEventSendRp, luckymoneyid);
		// 消息
		Map<String,Object> obj = Maps.newHashMap();
		Map<String,Object> data = Maps.newHashMap();
		data.put("type", 4);
		data.put("subtype", 302);
		Map<String,Object> info = Maps.newHashMap();
		info.put("redid", luckymoneyid);
		info.put("comment", "大吉大利");
		
		data.put("info", info);
		obj.put("Data", JSONObject.toJSONString(data));
		obj.put("Desc", "新红包");
		QQIMComponent oneComponent = new QQIMComponent();
    	// 发群消息 
		System.out.println(oneComponent.sendMsgToClub(obj, clubid));
		
		
	}
	
	
	 /**
     * 防止误差，输入输出是单位是分，整型
     * 如果返回是null，说明传入的参数出错了
     * @param amount
     * @param n
     * @return
     */
    public static Integer[] resortLuckyMoney(int amount, int n) {
    	Random rn = new Random();
        if(amount<n)
            return null;
        amount = amount-n;
        Integer[] list = new Integer[n];
        
        Float[] w = new Float[n];
        float wMax = 0f;
        for (int i = 0; i < n; i++) {
            list[i] = 0;
            float w0 = rn.nextFloat() * rn.nextFloat() + 0.01f;
            if(rn.nextFloat()<0.05)
                w0 = rn.nextFloat()*0.01f/n+0.01f; 
            wMax += w0;
            w[i] = w0;
        }
        if (amount <= 1 || wMax < 0.01)
            list[rn.nextInt(n)] = amount;
        else {
            int total = 0;
            for (int i = 0; i < n; i++) {
                int testAmount = (int) (amount * w[i] / wMax);                               
                if (testAmount + total > amount) {
                    testAmount = amount - total;
                    list[i] = testAmount;
                    total += testAmount;
                    break;
                } else {
                    list[i] = testAmount;
                    total += testAmount;
                }
                if (i == n - 1) {
                    int diff = amount - total;
                    list[i] += diff;
                }
            }
        }

        for (int i = 0; i < list.length; i++) {
            list[i] += 1;
        }
        return list;
    }
    
    public static String getBatchNo(){
    	String todayStr = new SimpleDateFormat("yyyyMMdd").format(new Date());
    	Withdraw withdraw = Withdraw.dao.findFirst("select * from club_cashwithdraw where batch_no like '"+todayStr+"%' order by batch_no desc limit 1");
    	if(withdraw == null){
    		return todayStr + String.format("%08d", 1);
    	} else {
    		Long batch_no = Long.valueOf(withdraw.getStr("batch_no"));
    		batch_no = batch_no + 1L;
    		return String.valueOf(batch_no);
    	}
    }
	
    public final  static String xiaomi = "64985869513831";
	
	/**
	 * 2、您的提现操作已完成,提现金额已转账至支付宝
	 */
	public static void withdrawcomplete(String to){
		String text = "您的提现操作已完成,提现金额已转账至支付宝";
		QQIMComponent qqIMComponent = new QQIMComponent();
		qqIMComponent.sendMsg(text, xiaomi, to);
	}
	
	/**
	 * 2、您的提现操作已完成,提现金额已转账至支付宝
	 */
	public static void withdrawfail(String text,String to){
		QQIMComponent qqIMComponent = new QQIMComponent();
		qqIMComponent.sendMsg("您的提现申请未通过,"+text, xiaomi, to);
	}
	
	public static void main(String[] args) {
		System.out.println(String.format("%04d", 2342));
		/*
		Map map = Maps.newHashMap();
		map.put("name", null);
		
		System.out.println(String.valueOf(map.get("name1")).getClass());
		System.out.println(String.valueOf(map.get("name1") == null));
		
		Object obj = null;
	    String strByStringValueOf = String.valueOf(obj);
	    if (strByStringValueOf == null) {
	        System.out.println("strByStringValueOf is null ");//不执行
	    }
	    if (strByStringValueOf != null && strByStringValueOf.equals("null")) {
	        System.out.println("strByStringValueOf is not null, is \"null\" ");//执行
	    }
//	    System.out.println(getBatchNo());
		/*
		Calendar cal = Calendar.getInstance();
		cal.set(Calendar.DAY_OF_MONTH, 1);
		Date start = cal.getTime();
		System.out.println(new SimpleDateFormat("yyyy-MM-dd").format(start) );
		cal.set(Calendar.MONTH, cal.get(Calendar.MONTH)+1);
		Date end = cal.getTime();
		System.out.println(new SimpleDateFormat("yyyy-MM-dd").format(end) );
		UserClub userclub = UserClub.dao.findFirst("select count(DISTINCT userid) as count  from club_userclub where club_userclub.clubid ="+10002);
		System.out.println(userclub.getInt("count"));
		*/
	}
	
	
}
